import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;

import javax.swing.JPanel;

/**
 * Copyright (C) 2013  Arun Lee & Bryce Nagareda
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Draw the dial face for equatorial sundial, 
 * 	everything should be in scale to the given radius
 * @author Arun Lee
 */
public class DrawEDialFace extends JPanel implements Printable{
	private static final long serialVersionUID = 1L;
	private double radius;
	private double[] hourlines;
	private String timezone;
	private int height;
	private int width;
	private double side = 45;
	/**
	 * constructor - initialized variables for drawing hour lines.
	 * 
	 * @param hrl hour lines
	 * @param S south
	 * @param tz timezone
	 */
	public DrawEDialFace(double rad, double[] hrl, String tz){
		this.radius = rad;
		this.hourlines = hrl;
		this.timezone = tz;
		this.width =  (int) (this.radius/0.2321);
		this.height = (int) (this.side/0.09);		
		setBackground(Color.white);
		setPreferredSize(new Dimension(this.width, this.height));
	}
	/*
	 * (non-Javadoc)
	 * @see javax.swing.JComponent#paint(java.awt.Graphics)
	 */
	public void paint(Graphics canvas){
		super.paintComponent(canvas);
		Graphics2D canvas2d = (Graphics2D)canvas;
		//initializing
		String[] hours = {"VI", "", "VII", "", "VIII", "", "IX", "", "X", "", "XI", "", "XII", 
				"", "I", "", "II", "", "III", "", "IV", "", "V", "", "VI"};
		double xtl = this.width*0.07, ytl = this.height*0.09, xtr = this.width-this.width*0.14, ytr = this.height*0.09, 
				xbl = this.width*0.07, ybl = this.height-this.height*0.09, xbr = this.width-this.width*0.14, ybr = this.height-this.height*0.09,
				midx = this.width*0.4626, midy = this.height/2;
		//draw the frame of dial face
		canvas2d.drawRect((int)xtl, (int)ytl, (int)(this.width*0.79), (int)(this.height*0.82));
		canvas2d.setColor(Color.blue);
		canvas2d.drawLine((int)(this.width*0.2306), (int)ytl, (int)(this.width*0.2306), (int)ybl);
		canvas2d.drawLine((int)(this.width*0.4626), (int)ytl, (int)(this.width*0.4626), (int)ybl);
		canvas2d.drawLine((int)(this.width*0.6946), (int)ytl, (int)(this.width*0.6946), (int)ybl);
		canvas2d.setColor(Color.black);
		canvas2d.drawLine((int)(xtl+this.width*0.79), (int)midy, (int)this.width, (int)midy);
		//initialize variables used for drawing of hour lines
		double sunrise = 6;
		double degree;
		int tempX = 0, tempY = 0;
		double length = 0;
		boolean extra = false;
		double indicatorAngleR = Math.atan((this.width*0.4626-this.width*0.2306)/(midy-ytl));
		double indicatorAngleD = 90-Math.toDegrees(indicatorAngleR);
		//draw the north portion
		for(int i = 0; i < this.hourlines.length; i++){
			degree = (-this.hourlines[i]) * Math.PI/180;
			//if the angle is less than 45 then we need to draw an extra line
			if(Math.abs(this.hourlines[i]) < indicatorAngleD){
				length = this.radius/(Math.abs(Math.cos(degree)));
				extra = true;
			}
			else {
				length = (ybl - this.height/2)/(Math.abs(Math.sin(degree)));
			}
			// if it is 30 mins line
			if(sunrise % 1 > 0){
	        	tempX = (int) (midx - length*0.8 * Math.cos(degree));
	        	tempY = (int) (midy - length*0.8 * Math.sin(degree));
	        	extra = false;
	        }
	        else {
	        	tempX = (int) (midx - length * Math.cos(degree));
			    tempY = (int) (midy - length * Math.sin(degree));
	        }
		    canvas.drawLine(tempX, tempY, (int)midx, (int)midy);
		    //draw the hour mark
		    if(extra){
		    	canvas2d.drawLine(tempX, tempY, (int) xtl, tempY);
		    	canvas.drawString(hours[i], (int)(xtl*1.05), (int)(tempY*0.99));
		    }
		    else if(tempY > this.height/2){
		    	canvas.drawString(hours[i], (int)(tempX*0.95), (int)(tempY*0.99));
		    }
		    else {
		    	canvas.drawString(hours[i], (int)(tempX*0.93), (int)(tempY*1.3));
		    }
		    sunrise = sunrise + 0.5;
		    extra = false;
		}
		//draw the south portion, basicly same as the north portion
	    for(int i = 0; i < this.hourlines.length; i++){
	    	degree = (this.hourlines[i]) * Math.PI/180;
	    	if(Math.abs(this.hourlines[i]) < indicatorAngleD){
				length = this.radius/(Math.abs(Math.cos(degree)));
				extra = true;
			}
			else {
				length = (ybl - this.height/2)/(Math.abs(Math.sin(degree)));
			}
	    	
	    	if(sunrise % 1 > 0){
	        	tempX = (int) (midx + length * Math.cos(degree));
	        	tempY = (int) (midy + length * Math.sin(degree));
	        }
	        else {
			    tempX = (int) (midx + length*0.8 * Math.cos(degree));
			    tempY = (int) (midy + length*0.8 * Math.sin(degree));
			    extra = false;
	        }
	    	
		    canvas.drawLine(tempX, tempY, (int)midx, (int)midy);
		    if(extra){
		    	canvas2d.drawLine(tempX, tempY, (int) xtr, tempY);
		    	canvas.drawString(hours[i], (int)(xtr*0.97), (int)(tempY*0.99));
		    }
		    else if(tempY > this.height/2){
		    	 canvas.drawString(hours[i], (int)(tempX*0.95), (int)(tempY*0.99));
		    }
		    else {
		    	canvas.drawString(hours[i], (int)(tempX*0.93), (int)(tempY*1.3));
		    }
		    sunrise = sunrise + 0.5;
		    extra = false;
	    }
		//finish-up
	    canvas2d.setColor(Color.yellow);
	    canvas2d.drawLine((int)(midx*0.95), (int)midy, (int)(midx*1.05), (int)midy);
	    canvas2d.setFont(new Font("Arial", Font.PLAIN, 15));
	    canvas2d.setColor(Color.black);
	    canvas2d.drawString(this.timezone, (int) midx, (int) (ytl*0.98));
	    canvas2d.setColor(Color.white);
	    canvas2d.fillRect((int)(midx*0.8), (int)(midy-((this.height*0.05)/2)), (int)(this.width*0.05), (int)(this.height*0.05));
	    canvas2d.setFont(new Font("Arial", Font.BOLD, (int)(this.width*0.05)));
	    canvas2d.setColor(Color.black);
	    canvas2d.rotate(Math.toRadians(270), midx*0.8+this.width*0.04, midy+((this.height*0.04)/2));
	    canvas2d.drawString("N", (int)(midx*0.8+this.width*0.04), (int)(midy+((this.height*0.04)/2)));
		
	}
		
	@Override
	public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) {
		// number of page is zero based
        if (pageIndex > 0) {
            return NO_SUCH_PAGE;
        }

        // User (0,0) is typically outside the
        // imageable area, so we must translate
        // by the X and Y values in the PageFormat
        // to avoid clipping.
        Graphics2D g2d = (Graphics2D) graphics;
        g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

        // Now we perform our rendering
        //This prints a grey page with the applet name at the top, but no lines.
        //why no lines?
        this.paint(g2d);

        // tell the caller that this page is part
        // of the printed document
        return PAGE_EXISTS;
	}
}
